package com.thghh.fsbrowser.fs;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * com.thghh.fsbrowser.fs.IFilePathSystem
 * 
 * @author pengzhikang
 * @param <FilePathPath>
 * @date 2018年9月22日下午11:02:30
 * @since 1.0
 */
interface IFileSystem extends Closeable {


	/* -- Normalization and construction -- */

	/**
	 * Return the local FilePathsystem's name-separator character.
	 */
	public char getSeparator();

	/**
	 * Return the local FilePathsystem's path-separator character.
	 */
	public char getPathSeparator();

	/**
	 * Convert the given pathname string to normal form. If the string is
	 * already in normal form then it is simply returned.
	 */
	public String normalize(String path);

	/**
	 * Compute the length of this pathname string's prefix. The pathname string
	 * must be in normal form.
	 */
	public int prefixLength(String path);

	/**
	 * Resolve the child pathname string against the parent. Both strings must
	 * be in normal form, and the result will be in normal form.
	 */
	public String resolve(String parent, String child);

	/**
	 * Return the parent pathname string to be used when the parent-directory
	 * argument in one of the two-argument FilePath constructors is the empty
	 * pathname.
	 */
	public String getDefaultParent();

	/**
	 * Post-process the given URI path string if necessary. This is used on
	 * win32, e.g., to transform "/c:/foo" into "c:/foo". The path string still
	 * has slash separators; code in the FilePath class will translate them
	 * after this method returns.
	 */
	public String fromURIPath(String path);

	/* -- Path operations -- */

	/**
	 * Tell whether or not the given pathname is absolute.
	 */
	public boolean isAbsolute(FilePath f);

	/**
	 * Resolve the given pathname into absolute form. Invoked by the
	 * getAbsolutePath and getCanonicalPath methods in the FilePath class.
	 */
	public String resolve(FilePath f);

	public String canonicalize(String path) throws IOException;

	public static final int ACCESS_READ = 0x04;
	public static final int ACCESS_WRITE = 0x02;
	public static final int ACCESS_EXECUTE = 0x01;

	/**
	 * Check whether the FilePath or directory denoted by the given pathname may
	 * be accessed by this process. The second argument specifies which access,
	 * ACCESS_READ, ACCESS_WRITE or ACCESS_EXECUTE, to check. Return false if
	 * access is denied or an I/O error occurs
	 */
	public boolean checkAccess(FilePath f, int access);

	/**
	 * Set on or off the access permission (to owner only or to all) to the
	 * FilePath or directory denoted by the given pathname, based on the
	 * parameters enable, access and oweronly.
	 */
	public boolean setPermission(FilePath f, int access, boolean enable, boolean owneronly);

	/**
	 * Return the time at which the FilePath or directory denoted by the given
	 * pathname was last modified, or zero if it does not exist or some other
	 * I/O error occurs.
	 */
	public long getLastModifiedTime(FilePath f);

	/**
	 * Return the length in bytes of the FilePath denoted by the given pathname,
	 * or zero if it does not exist, is a directory, or some other I/O error
	 * occurs.
	 */
	public long getLength(FilePath f);

	/* -- FilePath operations -- */

	/**
	 * Create a new empty FilePath with the given pathname. Return
	 * <code>true</code> if the FilePath was created and <code>false</code> if a
	 * FilePath or directory with the given pathname already exists. Throw an
	 * IOException if an I/O error occurs.
	 */
	public boolean createNewFile(FilePath filePath) throws IOException;

	/**
	 * Delete the FilePath or directory denoted by the given pathname, returning
	 * <code>true</code> if and only if the operation succeeds.
	 */
	public boolean delete(FilePath f);

	/**
	 * List the elements of the directory denoted by the given pathname. Return
	 * an array of strings naming the elements of the directory if successful;
	 * otherwise, return <code>null</code>.
	 */
	public String[] list(FilePath f);

	/**
	 * Create a new directory denoted by the given pathname, returning
	 * <code>true</code> if and only if the operation succeeds.
	 */
	public boolean createDirectory(FilePath f);

	/**
	 * Rename the FilePath or directory denoted by the first pathname to the
	 * second pathname, returning <code>true</code> if and only if the operation
	 * succeeds.
	 */
	public boolean rename(FilePath f1, FilePath f2);

	/**
	 * Set the last-modified time of the FilePath or directory denoted by the
	 * given pathname, returning <code>true</code> if and only if the operation
	 * succeeds.
	 */
	public boolean setLastModifiedTime(FilePath f, long time);

	/**
	 * Mark the FilePath or directory denoted by the given pathname as
	 * read-only, returning <code>true</code> if and only if the operation
	 * succeeds.
	 */
	public boolean setReadOnly(FilePath f);

	/* -- FilePathsystem interface -- */

	/**
	 * List the available FilePathsystem roots.
	 */
	public FilePath[] listRoots();
	
	/* -- Disk usage -- */
	public static final int SPACE_TOTAL = 0;
	public static final int SPACE_FREE = 1;
	public static final int SPACE_USABLE = 2;

	public long getSpace(FilePath f, int t);

	/* -- Basic infrastructure -- */

	/**
	 * Compare two pathnames lexicographically.
	 */
	public int compare(FilePath f1, FilePath f2);

	/**
	 * Compute the hash code of an pathname.
	 */
	public int hashCode(FilePath f);

	/**
	 * 打开输入流，读入指定文件
	 * 
	 * @param FilePathPath
	 * @return
	 * @author Zhikang.Peng
	 * @date 2018-09-2510:16:26
	 * @since 1.0
	 */
	public InputStream open(FilePath FilePathPath) throws IOException;

	/**
	 * 创建输出流，写入指定文件
	 * 
	 * @param FilePathPath
	 * @return
	 * @author Zhikang.Peng
	 * @date 2018-09-2510:17:40
	 * @since 1.0
	 */
	public OutputStream create(FilePath FilePathPath) throws IOException;

	public boolean exists(FilePath filePath);

	public boolean isDirectory(FilePath filePath);

	public boolean isFile(FilePath filePath);
	
	public String tmpdir();
	
	public boolean isConnected();
	
	public FilePath filePath(String pathname);
}
